/**
 * @file   loggerholder.h
 * @Author Alexandre Chassany (alexandre.chassany@gmail.com)
 * @date   February 2011
 * @brief  Definition of LoggerHolder
 * @note   Based on a tutorial on meta programming on www.developpez.com
 *
 * Poum-tchak is a free sound manipulation and synthesis, 
 * real-time and interactive music-clip rendering.
 *
 * Copyright (C) 2011  Chassany Alexandre and Gonzalez Antoine.
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * he Free Software Foundation, either version 3 of the License, or
 * at your option) any later version.
 *
 * is program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 *
 */

#ifndef _ELIXIR_LOGGERHOLDER_H_
#define _ELIXIR_LOGGERHOLDER_H_

#include <core/typelist.h>
#include <core/ilogger.h>

#include <list>
#include <sstream>

namespace Elixir
{
  /**
   *@class LoggerList
   *@brief Define a list logger
   *@see Elixir::ILogger
   **/
   template <class T>
   struct LoggerList : public std::list<ILogger*> {};
  
  /**
   * Define the end of the recursion of the typelist
   */
  template <> 
  struct LoggerList<NullType> : public std::list<ILogger*>{};
  
  /**
   * Template specialisation to handle TypeList recursion
   */
  template <class H, class T>
  struct LoggerList<TypeList<H,T> >
	: public std::list<ILogger*>
  {
	typedef TypeList<H,T> List_t;
	typedef H Head_t;
	typedef T Tail_t;
	
	/**
	 * Create a logger of type head and merge the content of its list
	 * with the LoggerList<Tail>
	 */
	LoggerList();

	/**
	 * Delete only the logger allocated in the constructor
	 */
	~LoggerList();
  };
  
  /**
   *@class LoggerHolder
   *@brief Hold a list of logger to write messages in them
   *@note Use this object to define statically a list of logger
   * you wnat to use. Then log messages through this object.
   **/
  template<class T>
  class LoggerHolder
  {
  public:
	
	LoggerHolder();
	~LoggerHolder();
	
	/**
	 *@brief log a message
	 *@details Use this methode to log a message in your loggers
	 *@param message : the message to log
	 */
	template <class U>
	LoggerHolder<T>& operator<<(const U& message);
	
  private:
	LoggerList<T> loggers_; //!< list of the loggers
  };

  /**
   * Include implementation and specialisation of template classes
   */
  #include "loggerholder-inl.h"
}
#endif // _ELIXIR_LOGGERHOLDER_H_
